﻿# -*- coding: UTF-8 -*-
import csv
import hashlib
import itertools
import json
import os
import random
import string
import time
from datetime import datetime

import requests
import base64
from Crypto.Hash import MD5

from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from tqdm import tqdm


class GetInterfaceToken:
    def __init__(self):
        self.__api_id = "1"
        self.__api_secret = "1"
        self.__private_key = "1"

    def __getRandomString(self, length=10):
        letters = string.ascii_letters
        return ''.join(random.choice(letters) for i in range(length))

    def __generate_time_stamp(self):
        timestamp = str(time.time_ns())[:13]
        # 转换为毫秒
        return timestamp

    def __getSHA256Str(self, t_str):
        hash_object = hashlib.sha256()
        # 将字符串编码为字节，然后更新哈希对象
        hash_object.update(t_str.encode())
        sign = hash_object.hexdigest()
        return sign
        # hash_object = hashlib.sha256(str.encode('utf-8'))
        # hash_hex = hash_object.hexdigest()
        # return hash_hex

    def __getPrivateKey(self):
        decoded_key = base64.b64decode(self.__private_key.encode())
        key_spec = RSA.importKey(decoded_key)
        return key_spec

    def __getAPISign(self, nonce, sign, tmp_time):
        str_text = f"apiId={self.__api_id}&apiSecret={self.__api_secret}&nonce={nonce}&sign={sign}&time={tmp_time}&"
        decoded_key = base64.b64decode(self.__private_key.encode())
        key_spec = RSA.importKey(decoded_key)

        key_bytes = key_spec.export_key()
        key_spec = RSA.import_key(key_bytes)
        signature = pkcs1_15.new(key_spec)
        hash_value = MD5.new(str_text.encode())
        signature_bytes = signature.sign(hash_value)
        result = base64.b64encode(signature_bytes).decode()
        return result

    def __getCode(self, nonce, tmp_time, sign, api_sign):
        url = "http://zzjk.zztaxi.cn:8090/netCarMonitor/interface/auth/serverVerify.do"
        headers = {
            "Content-Type": "application/json;charset=UTF-8",
        }
        data = {
            "apiId": self.__api_id,
            "apiSecret": self.__api_secret,
            "nonce": nonce,
            "sign": sign,
            "time": tmp_time,
            "apiSign": api_sign
        }

        print(data)

        data = json.dumps(data)

        response = requests.post(url, headers=headers, data=data)
        data = response.json()
        return data['data']

    def __getInterfaceToken(self, code):
        url = "http://zzjk.zztaxi.cn:8090/netCarMonitor/interface/auth/getToken.do"
        headers = {
            "Content-Type": "application/json;charset=UTF-8",
        }
        data = {
            "apiId": self.__api_id,
            "apiSecret": self.__api_secret,
            "code": code
        }
        response = requests.post(url, headers=headers, data=json.dumps(data))
        data = response.json()
        return data['data']

    def getToken(self):
        tmp_time = str(time.time_ns())[:13]
        nonce = self.__getRandomString()
        tmp_str = f"{self.__api_id}&{tmp_time}&{nonce}"
        sign = self.__getSHA256Str(tmp_str)
        api_sign = self.__getAPISign(nonce=nonce, sign=sign, tmp_time=tmp_time)
        code = self.__getCode(nonce=nonce, tmp_time=tmp_time, sign=sign, api_sign=api_sign)
        print(code)
        i_token = self.__getInterfaceToken(code)
        print(i_token)
        with open(f'./token.txt', 'w') as f:
            f.write(i_token)

class TaxiPassengerCheckInterface:
    def __init__(self, interface_token):
        self.__interface_token = interface_token
        self.__BASE_URL = "http://zzjk.zztaxi.cn:8090/netCarMonitor/interfaceQuery"

        self.__header = {
            "interfaceToken": self.__interface_token
        }

    def readDataFromCSV(self, csv_path):
        driver_basic_info_list = []
        with open(csv_path, 'r', encoding="utf-8") as file:
            # with open(csv_path, 'r') as file:
            reader = csv.DictReader(file)
            for row in reader:
                tmp_driver_dict = {}
                tmp_driver_dict["司机编号"] = row.get("\ufeff司机编号").replace("=", "").replace('"', "")
                # tmp_driver_dict["司机编号"] = row.get("司机编号")
                tmp_driver_dict["司机姓名"] = row.get("司机姓名")
                # tmp_driver_dict["司机身份证号"] = row.get("司机身份证号/驾驶证号")
                tmp_driver_dict["司机身份证号"] = row.get("司机身份证号/驾驶证号").replace("=", "").replace('"', "")
                tmp_driver_dict["车牌号"] = row.get("车牌号")
                tmp_driver_dict["有无人证"] = None
                tmp_driver_dict["有无车证"] = None
                driver_basic_info_list.append(tmp_driver_dict)
        return driver_basic_info_list

    def saveResultToCSV(self, result_file_name, data):
        with open(f'{result_file_name}_{datetime.now().strftime("%Y_%m_%d")}.csv', 'w', encoding='utf-8', newline='') as csvfile:
            # 获取第一个数据作为表头
            fieldnames = list(data[0].keys())
            csvwriter = csv.DictWriter(csvfile, fieldnames=fieldnames)
            csvwriter.writeheader()
            csvwriter.writerows(data)

    def checkLegalityByIDAndVehicleNo(self):
        url = f"{self.__BASE_URL}/batchGetVerificationStatus.do"
        data = {
            "parameter": "[{'vehicleNo': '豫AF836815', 'idCardNo': '1410122198905210018'}]"
        }
        response = requests.get(url, headers=self.__header, params=data)
        return response

    def checkOffLineCar(self):
        url = f'{self.__BASE_URL}/getofflineGpsList.do'
        params = {
            "vehicleNo": ' 豫A234',
        }
        response = requests.get(url, headers=self.__header, params=params)
        return response

    def requestInterface(self, url, params, result_list):
        print('正在请求')

        try:
            response = requests.get(url, headers=self.__header, params=params, timeout=60)
            print('请求完成')
            if response.status_code == 200:
                if response.json()["data"]:
                    print(response.status_code)
                    result_list.extend(response.json()['data'])
                elif response.json()["reason"] == "操作失败:您发送的请求次数受限!":
                    print("操作失败:您发送的请求次数受限! 正重新请求")
                    self.requestInterface(url, params, result_list)
            else:
                print("未知错误")
                print(response.status_code, response.text)
        except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
            print("请求超时重新请求")
            self.requestInterface(url, params, result_list)
            time.sleep(10)
        except Exception as e:
            print(e)
            raise "异常错误,请检查处理"

    def checkLegalityByVehicleNo(self, car_number_list):
        check_car_result = []
        url = f'{self.__BASE_URL}/batchGetVehicleVerificationStatusByVehicleNo.do'
        # 接口只能一次性最大148条数据，不然报400
        block_size = 100
        # 使用循环和切片来处理列表切片
        join_thread_list = []
        for i in tqdm(range(0, len(car_number_list), block_size)):
            # 获取当前块
            block = car_number_list[i:i + block_size]
            # 执行操作
            params = {
                'parameter': f"{block}"
            }
            self.requestInterface(url, params, check_car_result)

        return check_car_result

    def checkLegalityByID(self, id_number_list):
        check_person_result = []
        url = f'{self.__BASE_URL}/batchGetDriverVerificationStatusByIdCardNo.do'

        block_size = 100
        # 使用循环和切片来处理列表切片
        join_thread_list = []
        for i in tqdm(range(0, len(id_number_list), block_size)):
            # 获取当前块
            block = id_number_list[i:i + block_size]
            # 执行操作
            params = {
                'parameter': f"{block}"
            }

            self.requestInterface(url, params, check_person_result)
            time.sleep(1)

        return check_person_result

        # params = {
        #     'parameter': f"{id_number_list}"
        # }
        # response = requests.get(url, headers=self.__header, params=params).json()
        # return response['data']


def getCarNumberList(drivers_base_info_list: list):
    car_number_list = []
    for drivers_base_info in drivers_base_info_list:
        tmp_car_dict = {}
        if drivers_base_info["车牌号"]:
            tmp_car_dict["vehicleNo"] = drivers_base_info["车牌号"]
            car_number_list.append(tmp_car_dict)
    return car_number_list


def getIDNumberList(drivers_base_info_list: list):
    id_number_list = []
    for drivers_base_info in drivers_base_info_list:
        tmp_id_dict = {}
        if drivers_base_info["司机身份证号"]:
            tmp_id_dict["idCardNo"] = drivers_base_info["司机身份证号"]

        id_number_list.append(tmp_id_dict)
    return id_number_list


def matchDriverInformationByCarNumber(check_car_result, drivers_base_info_list):
    # 这个方法进行了浅拷贝就不用返回赋值了， 直接更新drivers_base_info_list
    for car_result, drivers_base_info in itertools.product(check_car_result, drivers_base_info_list):
        if car_result['vehicleNo'] == drivers_base_info['车牌号']:
            drivers_base_info['有无车证'] = car_result['status']

    # for car_result in check_car_result:
    #     for drivers_base_info in drivers_base_info_list:
    #         if car_result['idCardNo'] == drivers_base_info['车牌号']:
    #             drivers_base_info['有无车证'] = car_result['status']


def matchDriverInformationByIDNumber(check_person_result, drivers_base_info_list):
    # 这个方法进行了浅拷贝就不用返回赋值了
    for person_result, drivers_base_info in itertools.product(check_person_result, drivers_base_info_list):
        if person_result['idCardNo'] == drivers_base_info['司机身份证号']:
            drivers_base_info['有无人证'] = person_result['status']


    # for person_result in check_person_result:
    #     for drivers_base_info in drivers_base_info_list:
    #         if person_result['idCardNo'] == drivers_base_info['司机身份证号']:
    #             drivers_base_info['有无人证'] = person_result['status']


def judgementTokenIsValid(token):
    url = "http://zzjk.zztaxi.cn:8090/netCarMonitor/interfaceQuery/batchGetDriverVerificationStatusByIdCardNo.do"
    headers = {
        "interfaceToken": token
    }

    data = {
        "parameter": '[{"vehicleNo": "豫ADF5751"}]'
    }

    response = requests.get(url, headers=headers, params=data).json()

    if response["status"] == "failed":

        return False
    else:
        return True


def main(file_name):
    if not os.path.exists('./token.txt'):
        Get_InterFace_Token = GetInterfaceToken()
        Get_InterFace_Token.getToken()
        print("Token获取完毕,正重新运行程序")
        main(file_name)
        return

    with open('./token.txt', 'r', encoding='utf-8') as f:
        interface_token = f.read()

    if not judgementTokenIsValid(interface_token):
        Get_InterFace_Token = GetInterfaceToken()
        Get_InterFace_Token.getToken()
        main(file_name)
        return

    Taxi_Passenger_Check_Interface = TaxiPassengerCheckInterface(interface_token)
    csv_path = f"./data_cube/uploads/{file_name}"
    print(csv_path)
    drivers_base_info_list = Taxi_Passenger_Check_Interface.readDataFromCSV(csv_path)
    print(drivers_base_info_list)
    #
    # # 判断已经查询过的不进行查询
    #
    #
    # car_number_list = getCarNumberList(drivers_base_info_list)
    # print(car_number_list)
    # # 车证 车牌号
    # check_car_result = Taxi_Passenger_Check_Interface.checkLegalityByVehicleNo(car_number_list)
    # matchDriverInformationByCarNumber(check_car_result, drivers_base_info_list)
    # print('车证查询完毕')
    #
    # # # 人证 身份证号
    # id_number_list = getIDNumberList(drivers_base_info_list)
    # check_person_result = Taxi_Passenger_Check_Interface.checkLegalityByID(id_number_list)
    # matchDriverInformationByIDNumber(check_person_result, drivers_base_info_list)
    # print('人证查询完毕')
    Taxi_Passenger_Check_Interface.saveResultToCSV("./data_cube/result/郑州查询后的结构", drivers_base_info_list)

